package com.linb.pan.server.modules.share.controller;


import com.google.common.base.Splitter;
import com.linb.pan.core.constants.BPanConstants;
import com.linb.pan.core.response.R;
import com.linb.pan.core.utils.IdUtil;
import com.linb.pan.server.common.annotation.LoginIgnore;
import com.linb.pan.server.common.annotation.NeedShareCode;
import com.linb.pan.server.common.utils.ShareIdUtil;
import com.linb.pan.server.common.utils.UserIdUtil;
import com.linb.pan.server.modules.file.vo.BPanUserFileVO;
import com.linb.pan.server.modules.share.context.*;
import com.linb.pan.server.modules.share.converter.ShareConverter;
import com.linb.pan.server.modules.share.po.CancelSharePO;
import com.linb.pan.server.modules.share.po.CheckShareCodePO;
import com.linb.pan.server.modules.share.po.CreateShareUrlPO;
import com.linb.pan.server.modules.share.po.ShareSavePO;
import com.linb.pan.server.modules.share.service.IShareService;
import com.linb.pan.server.modules.share.vo.BPanShareUrlListVO;
import com.linb.pan.server.modules.share.vo.BPanShareUrlVO;
import com.linb.pan.server.modules.share.vo.ShareDetailVO;
import com.linb.pan.server.modules.share.vo.ShareSimpleDetailVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "分享模块")
@RestController
@Validated
public class ShareController {

    @Autowired
    private ShareConverter shareConverter;

    @Autowired
    private IShareService shareService;

    @PostMapping("share")
    @ApiOperation("创建分享链接")
    public R<BPanShareUrlVO> create(@Validated @RequestBody CreateShareUrlPO po) {
        CreateShareUrlContext context = shareConverter.createShareUrlPO2CreateShareUrlContext(po);

        List<Long> shareFileIdList = Splitter.on(BPanConstants.COMMON_SEPARATOR).splitToList(po.getShareFileIds())
                .stream().map(IdUtil::decrypt).collect(Collectors.toList());
        context.setShareFileIdList(shareFileIdList);

        BPanShareUrlVO vo = shareService.create(context);
        return R.data(vo);
    }

    @GetMapping("shares")
    @ApiOperation("查看我的分享列表")
    public R<List<BPanShareUrlListVO>> getShares() {
        QueryShareListContext context = new QueryShareListContext();
        context.setUserId(UserIdUtil.get());
        List<BPanShareUrlListVO> voList = shareService.getShares(context);
        return R.data(voList);
    }

    @DeleteMapping("share")
    @ApiOperation("取消分享")
    public R cancelShare(@Validated @RequestBody CancelSharePO po) {
        CancelShareContext context = new CancelShareContext();
        context.setUserId(UserIdUtil.get());
        List<Long> shareIdList = Splitter.on(BPanConstants.COMMON_SEPARATOR).splitToList(po.getShareIds())
                .stream().map(IdUtil::decrypt).collect(Collectors.toList());
        context.setShareIdList(shareIdList);
        shareService.cancelShare(context);
        return R.success();
    }

    @GetMapping("all_shares")
    @ApiOperation("用于测试--查看所有人的分享列表")
    public R<List<BPanShareUrlListVO>> allShares() {
        List<BPanShareUrlListVO> voList = shareService.allShares();
        return R.data(voList);
    }

    @PostMapping("share/code/check")
    @ApiOperation("校验分享码")
    public R<String> checkShareCode(@Validated @RequestBody CheckShareCodePO po) {
        CheckShareCodeContext context = new CheckShareCodeContext();
        context.setShareId(IdUtil.decrypt(po.getShareId()));
        context.setShareCode(po.getShareCode());
        String token = shareService.checkShareCode(context);
        return R.data(token);
    }

    @GetMapping("share")
    @ApiOperation("查询分享详情")
    @LoginIgnore //不需要登录
    @NeedShareCode //需要分享的token
    public R<ShareDetailVO> detail() {
        QueryShareDetailContext context = new QueryShareDetailContext();
        context.setShareId(ShareIdUtil.get());//shareId从ThreadLocal中获取
        ShareDetailVO vo = shareService.detail(context);
        return R.data(vo);
    }

    @GetMapping("share/simple")
    @ApiOperation("查询简单分享详情")
    @LoginIgnore
    public R<ShareSimpleDetailVO> simpleDetail(@NotBlank(message = "分享的id不能为空")
                                               @RequestParam(value = "shareId", required = false) String shareId) {
        QueryShareSimpleDetailContext context = new QueryShareSimpleDetailContext();
        context.setShareId(IdUtil.decrypt(shareId));
        ShareSimpleDetailVO vo = shareService.simpleDetail(context);
        return R.data(vo);
    }

    @ApiOperation("获取下一级文件列表")
    @GetMapping("share/file/list")
    @LoginIgnore
    @NeedShareCode
    public R<List<BPanUserFileVO>> fileList(@NotBlank(message = "父文件夹id不能为空")
                                            @RequestParam(value = "parentId", required = false) String parentId) {
        QueryChildFileListContext context = new QueryChildFileListContext();
        context.setShareId(ShareIdUtil.get());
        context.setParentId(IdUtil.decrypt(parentId));
        List<BPanUserFileVO> voList = shareService.fileList(context);
        return R.data(voList);
    }

    @ApiOperation("保存分享文件")
    @PostMapping("share/save")
    @NeedShareCode
    public R saveFiles(@Validated @RequestBody ShareSavePO po) {
        ShareSaveContext context = new ShareSaveContext();
        List<Long> fileIdList = Splitter.on(BPanConstants.COMMON_SEPARATOR).splitToList(po.getFileIds())
                .stream().map(IdUtil::decrypt).collect(Collectors.toList());

        context.setShareId(ShareIdUtil.get());
        context.setUserId(UserIdUtil.get());
        context.setTargetParentId(IdUtil.decrypt(po.getTargetParentId()));
        context.setFileIdList(fileIdList);

        shareService.saveFiles(context);
        return R.success();
    }

    @ApiOperation("下载分享的文件")
    @NeedShareCode
    @GetMapping("share/file/download")
    public void download(@NotBlank(message = "文件id不能为空") @RequestParam(value = "fileId", required = false) String fileId,
                         HttpServletResponse response) {
        ShareFileDownloadContext context = new ShareFileDownloadContext();
        context.setUserId(UserIdUtil.get());
        context.setFileId(IdUtil.decrypt(fileId));
        context.setShareId(ShareIdUtil.get());
        context.setResponse(response);
        shareService.download(context);
    }

}
